﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeneralAlgorithm
{
    public class StringReverse
    {
        /// <summary>
        /// Reverse a string using Array.Reverse
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public string ReverseByArray(string original)
        {
            char[] str = original.ToCharArray();
            Array.Reverse(str);
            return new string(str);
        }

        /// <summary>
        /// Reverse a string using char buffer
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public string ReverseByCharBuffer(string original)
        {
            if (original == null || original.Length <=1)
            {
                return original;
            }

            char[] str = original.ToCharArray();

            char temp;
            int strLength = original.Length;
            for (int i = 0; i < strLength/2; i++)
            {
                temp = str[i];
                str[i] = str[strLength - 1 - i];
                str[strLength - 1 - i] = temp;
            }

            return new string(str);
        }

        /// <summary>
        /// Reverse a string using Stack
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public string ReverseByStack(string original)
        {
            Stack<char> strStack = new Stack<char>();

            foreach (char item in original)
            {
                strStack.Push(item);
            }

            char[] str = new char[original.Length];
            for (int i = 0; i < original.Length; i++)
            {
                str[i] = strStack.Pop();
            }

            return new string(str);
        }

        public string ReverseByXor(string original)
        {
            if (original == null || original.Length <= 1)
            {
                return original;
            }

            char[] str = original.ToCharArray();
            int strLength = original.Length;     

            for (int i = 0; i < strLength/2; i++)
            {
                str[i] ^= str[strLength - 1 - i];
                str[strLength - 1 - i] ^= str[i];
                str[i] ^= str[strLength - 1 - i];
            }

            return new string(str);
        }

        public void Benchmark(string description, Func<string, string> func, string original, int times)
        {
            Stopwatch sw = new Stopwatch();
           
            sw.Start();

            for (int j = 0; j < times; j++)
            {
                func(original);
            }

            sw.Stop();
            
            Debug.WriteLine("{0} Ticks {1} : called {2} times.",
                sw.ElapsedTicks, description, times);
        }

        



    }
}
